home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / fileutil / fileutils-3.16.tar.gz / fileutils-3.16.tar / fileutils-3.16 / lib / save-cwd.c < prev    next >
C/C++ Source or Header  |  1996-07-14  |  4KB  |  156 lines

  1. /* save-cwd.c -- Save and restore current working directory.
  2.    Copyright (C) 1995 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software Foundation,
  16.    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  17.  
  18. /* Written by Jim Meyering <meyering@na-net.ornl.gov>.  */
  19.  
  20. #ifdef HAVE_CONFIG_H
  21. # include "config.h"
  22. #endif
  23.  
  24. #include <stdio.h>
  25.  
  26. #ifdef STDC_HEADERS
  27. # include <stdlib.h>
  28. #endif
  29.  
  30. #ifdef HAVE_UNISTD_H
  31. # include <unistd.h>
  32. #endif
  33.  
  34. #ifdef HAVE_FCNTL_H
  35. # include <fcntl.h>
  36. #else
  37. # include <sys/file.h>
  38. #endif
  39.  
  40. #include <errno.h>
  41. # ifndef errno
  42. extern int errno;
  43. #endif
  44.  
  45. #include "save-cwd.h"
  46. #include "error.h"
  47.  
  48. char *xgetcwd __P((void));
  49.  
  50. /* Record the location of the current working directory in CWD so that
  51.    the program may change to other directories and later use restore_cwd
  52.    to return to the recorded location.  This function may allocate
  53.    space using malloc (via xgetcwd) or leave a file descriptor open;
  54.    use free_cwd to perform the necessary free or close.  Upon failure,
  55.    no memory is allocated, any locally opened file descriptors are
  56.    closed;  return non-zero -- in that case, free_cwd need not be
  57.    called, but doing so is ok.  Otherwise, return zero.  */
  58.  
  59. int
  60. save_cwd (cwd)
  61.      struct saved_cwd *cwd;
  62. {
  63.   static int have_working_fchdir = 1;
  64.  
  65.   cwd->desc = -1;
  66.   cwd->name = NULL;
  67.  
  68.   if (have_working_fchdir)
  69.     {
  70. #ifdef HAVE_FCHDIR
  71.       cwd->desc = open (".", O_RDONLY);
  72.       if (cwd->desc < 0)
  73.     {
  74.       error (0, errno, "cannot open current directory");
  75.       return 1;
  76.     }
  77.  
  78. # if __sun__ || sun
  79.       /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
  80.      so we have to fall back to chdir.  */
  81.       if (fchdir (cwd->desc))
  82.     {
  83.       if (errno == EINVAL)
  84.         {
  85.           close (cwd->desc);
  86.           cwd->desc = -1;
  87.           have_working_fchdir = 0;
  88.         }
  89.       else
  90.         {
  91.           error (0, errno, "current directory");
  92.           close (cwd->desc);
  93.           cwd->desc = -1;
  94.           return 1;
  95.         }
  96.     }
  97. # endif /* __sun__ || sun */
  98. #else
  99. #define fchdir(x) (abort (), 0)
  100.       have_working_fchdir = 0;
  101. #endif
  102.     }
  103.  
  104.   if (!have_working_fchdir)
  105.     {
  106.       cwd->name = xgetcwd ();
  107.       if (cwd->name == NULL)
  108.     {
  109.       error (0, errno, "cannot get current directory");
  110.       return 1;
  111.     }
  112.     }
  113.   return 0;
  114. }
  115.  
  116. /* Change to recorded location, CWD, in directory hierarchy.
  117.    If "saved working directory", NULL))
  118.    */
  119.  
  120. int
  121. restore_cwd (cwd, dest, from)
  122.      const struct saved_cwd *cwd;
  123.      const char *dest;
  124.      const char *from;
  125. {
  126.   int fail = 0;
  127.   if (cwd->desc >= 0)
  128.     {
  129.       if (fchdir (cwd->desc))
  130.     {
  131.       error (0, errno, "cannot return to %s%s%s",
  132.          (dest ? dest : "saved working directory"),
  133.          (from ? " from " : ""),
  134.          (from ? from : ""));
  135.       fail = 1;
  136.     }
  137.     }
  138.   else if (chdir (cwd->name) < 0)
  139.     {
  140.       error (0, errno, "%s", cwd->name);
  141.       fail = 1;
  142.     }
  143.   return fail;
  144. }
  145.  
  146. void
  147. free_cwd (cwd)
  148.      struct saved_cwd *cwd;
  149. {
  150.   if (cwd->desc >= 0)
  151.     close (cwd->desc);
  152.   if (cwd->name)
  153.     free (cwd->name);
  154. }
  155.  
  156.